home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / datedem.com / DATES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-11  |  8.5 KB  |  310 lines

  1. /* dates.c The dates functions to be used with C.  The dates are
  2.    input and output as strings with / delimiters.  A blank date
  3.    (ie not yet filled in) will be "  /  /  ".  The default is
  4.    similiar to Dbase format only using the year portion of the date
  5.    but if the CENTURY flag is true then the century will be used.
  6.    Released to the Public Domain for any purpose on 11 Mar 1989
  7.    Gerry Rohr.
  8. */
  9.  
  10. #include "dates.h"
  11. #include <string.h>
  12. #include <stdlib.h>
  13.  
  14. /* prototype for function which is local only */
  15. static int leapyear(int yr);  /* Returns true if leap year */
  16.  
  17. /* the following is a global array used by more than one of the functions */
  18. int MONTHTOTAL[] = {0,0,31,59,90,120,151,181,212,243,273,304,334,365};
  19.  
  20. char *dtoa(DATE in_date)
  21. {  /*Returns a character pointer to the date string representation
  22.      of the DATE type data set (long)
  23.    */
  24.    static char dt[11];   /* where the date is */
  25.    char *dp;             /* pointer returned */
  26.    char dt_st[11];       /* temp storage */
  27.    int i;
  28.  
  29.    strcpy(dt,DATE_TEMP);
  30.    dp = dt;
  31.    if(in_date == 0L)
  32.        return(dp);
  33.    else
  34.    {
  35.       ltoa(in_date,dt_st,10);  /* convert to a string */
  36.       for(i=0;i<2;i++,dp++) dp[0] = dt_st[4+i];  /* month */
  37.       dp++;  /* skip the slash */
  38.       for(i=0;i<2;i++,dp++) dp[0] = dt_st[6+i];  /* day */
  39.       dp++;
  40.       for(i=0;i<4;i++,dp++) dp[0] = dt_st[i];    /* year */
  41.       dp = dt;   /* reset pointer to beginning of string */
  42.       return(dp);
  43.    }
  44. } /* end of dtoa */
  45.  
  46. int day(DATE in_date)
  47. {  /* returns the day portion of a DATE */
  48.    int lo_date;
  49.  
  50.    if(in_date == NO_DATE) return(0);
  51.    lo_date = (in_date % 10000);
  52.    return(lo_date % 100);
  53. } /* end of day */
  54.  
  55. int month(DATE in_date)
  56. {  /* returns the month portion of a DATE */
  57.    int lo_date;
  58.  
  59.    if(in_date == NO_DATE) return(0);
  60.    lo_date = (in_date % 10000);
  61.    return(lo_date / 100);
  62. } /* end of month */
  63.  
  64. int year(DATE in_date,int cf)
  65. {  /* returns the year portion of a DATE. If cf is true returns
  66.       4 digit year else returns two digits
  67.    */
  68.    int hi_date;
  69.  
  70.    if(in_date == NO_DATE) return(0);
  71.    hi_date = (in_date / 10000);
  72.    if(cf)
  73.       return(hi_date);
  74.    else
  75.       return(hi_date % 100);
  76. } /* end of year */
  77.  
  78. void greg_to_jul(DATE in_date,JULDATE *jdt)
  79. {  /* converts the gregorian date to the julian date, operates on the
  80.       JULDATE structure defined by user.
  81.    */
  82.    int yr = year(in_date,1);
  83.    int mo = month(in_date);
  84.    int dy = day(in_date);
  85.  
  86.    jdt->yr = yr;
  87.    if(yr == 0 && mo == 0 && dy == 0) jdt->day = 0;
  88.    else
  89.    {
  90.       /* calculate leap year here */
  91.       if((leapyear(yr)) && (mo > 2)) jdt->day = 1;
  92.       else jdt->day = 0;
  93.       jdt->day = MONTHTOTAL[mo] + dy;
  94.    }
  95. } /* end of greg_to_jul */
  96.  
  97. DATE jul_to_greg(JULDATE *jdt)
  98. {  /* Converts user defined (pointer to user variable) julian date
  99.       to gregorian date, returns the gregorian date.
  100.    */
  101.    int i,workday = jdt->day;
  102.    int yr= jdt->yr;
  103.    int mo = 0,dy = 0;
  104.    DATE dt;
  105.  
  106.    if((jdt->yr > 0) || (jdt->day > 0))
  107.    {
  108.       if((leapyear(jdt->yr)) && (workday > 59))
  109.          workday -= 1;
  110.       i = 1;
  111.       while(workday > MONTHTOTAL[i]) i++;
  112.       mo = i - 1;
  113.       dy = workday - MONTHTOTAL[mo];
  114.       if((leapyear(jdt->yr)) && (jdt->day == 60))
  115.          dy += 1;
  116.    }
  117.    /* now to put the yr, mo, and dy into the DATE format */
  118.    dt = (long)yr;
  119.    dt = (dt * 100) + (long)mo;
  120.    dt = (dt * 100) + (long)dy;
  121.    return(dt);
  122. } /* end of jul_to_greg */
  123.  
  124. static int leapyear(int yr)
  125. {  /* Returns true (1) if year (all 4 digits) is a leap year, else
  126.       returns false (0).
  127.    */
  128.    if((((yr % 4) == 0) && (!((yr % 100) == 0))) || ((yr % 400) == 0))
  129.       return(1);
  130.    else
  131.       return(0);
  132. } /* end of leapyear */
  133.  
  134. void next_day(DATE *dt)
  135. {  /* Adds one day to the callers DATE variable.  Be sure to pass
  136.       the address to this function.  The callers data item is changed.
  137.    */
  138.    JULDATE jdt;
  139.  
  140.    greg_to_jul(*dt,&jdt);
  141.    jdt.day += 1;
  142.    if((leapyear(jdt.yr) && jdt.day == 367) ||
  143.       (!(leapyear(jdt.yr)) && (jdt.day == 366)))
  144.    {
  145.       jdt.yr += 1;
  146.       jdt.day = 1;
  147.    }
  148.    *dt = jul_to_greg(&jdt);
  149. } /* end of next_day */
  150.  
  151. void prev_day(DATE *dt)
  152. {  /* Subtracts one day to the callers DATE variable.  Be sure to pass
  153.       the address to this function.  The callers data item is changed.
  154.    */
  155.    JULDATE jdt;
  156.  
  157.    greg_to_jul(*dt,&jdt);
  158.    jdt.day -= 1;
  159.    if(jdt.day < 1)
  160.    {
  161.       jdt.yr -= 1;
  162.       if(leapyear(jdt.yr))
  163.          jdt.day = 366;
  164.       else
  165.          jdt.day = 365;
  166.    }
  167.    *dt = jul_to_greg(&jdt);
  168. } /* end of prev_day */
  169.  
  170. int valid_date(DATE dt)
  171. {  /* checks if date is valid. Return code indicates where the non valid
  172.       data was found.
  173.       0 = Valid date
  174.       1 = Month invalid
  175.       2 = Day invalid
  176.       4 = Year is invalid
  177.    */
  178.    int yr = year(dt,TRUE);
  179.    int mo = month(dt);
  180.    int dy = day(dt);
  181.    int rc = 0;
  182.  
  183.    if(dt != NO_DATE)  /* only check if some date is present */
  184.    {
  185.       switch(mo)
  186.       {
  187.          case 1 :
  188.          case 3 :
  189.          case 4 :
  190.          case 6 :
  191.          case 9 :
  192.          case 11:if(dy < 1 || dy > 31) rc += 2;
  193.                  break;
  194.          case 5 :
  195.          case 7 :
  196.          case 8 :
  197.          case 10:
  198.          case 12:if(dy < 1 || dy > 30) rc += 2;
  199.                  break;
  200.      case 2 :if((leapyear(yr) && (dy > 29)) ||
  201.                     (!(leapyear(yr)) && (dy > 28))) rc += 2;
  202.                  break;
  203.          default:rc += 1;
  204.       }
  205.       if(yr == 0) rc += 4;
  206.    }
  207.    return(rc);
  208. } /* end of valid_date */
  209.  
  210. char *month_name(int mon)
  211. { /* returns char pointer to month name given the number of the month
  212.      desired.  The string pointed to is read only.
  213.   */
  214.   static char *month[] = {"UNKNOWN","January","February","March",
  215.                          "April","May","June",
  216.                          "July","August","September",
  217.                          "October","November","December"};
  218.  
  219.    if(mon < 1 || mon > 12) return(month[0]);
  220.    else
  221.    return(month[mon]);
  222. } /* end of month_name */
  223.  
  224. char *day_name(DATE in_date)
  225. {   /* Returns character pointer to string name of the day of the week,
  226.        Note that this is a read only string.
  227.     */
  228.     static char *dayname[] = {"Sunday","Monday","Tuesday",
  229.                   "Wednesday","Thursday","Friday",
  230.                   "Saturday","UNKNOWN"};
  231.    int dow = zeller(in_date);
  232.  
  233.    if(dow < 0 || dow > 6) return(dayname[7]);
  234.    else return(dayname[dow]);
  235. } /* end of day_name */
  236.  
  237. int zeller(DATE dt)
  238. {  /* Gets day of week from date using Zeller's Congruence. */
  239.    int yr = year(dt,TRUE);
  240.    int mo = month(dt);
  241.    int dy = day(dt);
  242.    int century;
  243.  
  244.    if(mo > 2) mo -= 2;
  245.    else
  246.    {
  247.       mo = mo += 10;
  248.       yr -= 1;
  249.    }
  250.    century = yr / 100;
  251.    yr = (yr % 100);
  252.    return((dy - 1 + ((13 * mo - 1) / 5) + (5 * yr / 4) +
  253.           century / 4 - 2 * century + 1) % 7);
  254. } /* end of zeller */
  255.  
  256. char *jul_dt_st(JULDATE *jdt)
  257. {  /* returns char pointer to Julian date string.  This date string is
  258.       a read only string.
  259.    */
  260.    char day_st[4];
  261.    static char jdt_st[9];
  262.    char *s;
  263.    int i;
  264.  
  265.    s = jdt_st;
  266.    for(i=0;i<9;i++) jdt_st[i] = '\0';
  267.    if((jdt->yr == 0) && (jdt->day == 0)) strcpy(jdt_st,"YYYY/DDD");
  268.    else
  269.    {
  270.       itoa(jdt->yr,jdt_st,10);
  271.       strcat(jdt_st,"/");
  272.       itoa(jdt->day,day_st,10);
  273.       strcat(jdt_st,day_st);
  274.    }
  275.    return(s);
  276. } /* end of jul_dt_st */
  277.  
  278. char *full_date_st(DATE dt)
  279. {  /* Returns pointer to full date string.  This is a read only string. */
  280.    static char *dayname[] = {"Sunday","Monday","Tuesday",
  281.                              "Wednesday","Thursday","Friday",
  282.                              "Saturday","UNKNOWN"};
  283.    static char *monname[] = {"UNKNOWN","January","February","March",
  284.                              "April","May","June","July","August",
  285.                              "September","October",",November","December"};
  286.    static char fulldatest[30],ts[10];
  287.    char *s;
  288.    int yr = year(dt,TRUE);
  289.    int mo = month(dt);
  290.    int dy = day(dt);
  291.  
  292.    s = fulldatest;
  293.    if(mo == 0 && dy == 0 && yr == 0) strcpy(fulldatest,"No Date");
  294.    else
  295.    {
  296.       strcpy(fulldatest,dayname[zeller(dt)]);
  297.       strcat(fulldatest,", ");
  298.       strcat(fulldatest,monname[mo]);
  299.       strcat(fulldatest," ");
  300.       itoa(dy,ts,10);
  301.       strcat(fulldatest,ts);
  302.       strcat(fulldatest,", ");
  303.       itoa(yr,ts,10);
  304.       strcat(fulldatest,ts);
  305.    }
  306.    return(s);
  307. } /* end of full_date_st */
  308.  
  309. /* end of dates.c */
  310.